﻿
///分词器


#include "clexer.h"


#define C_Word_new0(lastStat, currWord, currLen, currNode) C_Word_new(lastStat, currWord, 0, currLen, currNode)


C_Symbol* clexer_loadScript(const char* script){
	printf("clexer_loadScript....\n");
	C_Symbol* rootNode = C_Symbol_new(lexNULL, ' ', 0, NULL);
	C_Symbol* currNode = rootNode;
	size_t len = strlen(script);
	char currWord[256];
	size_t currLen = 0;
	int lastStat = lexNULL;//上一个符号的状态
	size_t strStartPosi = 0;//字符串开始的位置
	size_t lineIndex = 0;//在当前行的运行位置
	for (size_t i = 0; i < len; i++){
		lineIndex++;
		//if (i > 200){ return; }
		unsigned char cc = script[i];
		if (cc == '\n'){//换行符--开始新行
			lineIndex = -1;
			continue;
		}
		//if (lastStat == lex字符串){//对支付串的持续处理
		//	if (cc == '\"' && script[i - 1] != '\\'){
		//		currNode = C_Word_new0(lastStat, NULL, i - strStartPosi, currNode);
		//	} else{
		//		continue;
		//	}
		//}
		//printf("打印.单词......%d.......%d.......%c\n", i, cc, cc);
		if ((cc >= 65 && cc <= 90) || (cc >= 97 && cc <= 122) || cc == '_'){//遇到单词的处理
			//printf("打印.单词......%d.......%d.......%c\n", i, cc, cc);
			if (lastStat != lex单词){
				lastStat = lex单词;
				currLen = 0;
			}
			currWord[currLen] = cc;
			currLen++;
		} else if (cc >= 48 && cc <= 57){//遇到数字的逻辑处理
			if (lastStat != lex单词 && lastStat != lex数字){
				lastStat = lex数字;
				currLen = 0;
			}
			currWord[currLen] = cc;
			currLen++;
			//printf("打印.数字......%D.......%d.......%c\n", i, cc, cc);
		} else{
			if (lastStat == lex单词){
				currNode = (C_Symbol*)C_Word_new0(lastStat, currWord, currLen, currNode);
			} else	if (lastStat == lex数字){
				currNode = (C_Symbol*)C_Word_new0(lastStat, currWord, currLen, currNode);
			}
			switch (cc){
				case '\"':
					if (lastStat != lex字符串){
						lastStat = lex字符串;
					} else	{
						lastStat = lex分割符;
					}
					size_t startPosi = i; 
					int offect = i + 1;
					while (script[offect] != '\"')	{
						offect++; 
						if (offect >= len){
							printf("游戏结束....\n");
							return rootNode;
						}
					}
					currLen = offect- startPosi;
					currNode = C_Word_new(lastStat, script, startPosi, currLen, currNode);
					i = offect;
					break;
				case ' ':
					lastStat = lex分割符;
					break;
				case '.':
					lastStat = lex分割符;
					currNode = C_Symbol_new(lastStat, '.', 5, currNode);
					break;
				case '(':
					lastStat = lex分割符;
					currNode = C_Symbol_new(lastStat, '(', 5, currNode);
					break;
				case ')':
					lastStat = lex分割符;
					currNode = C_Symbol_new(lastStat, ')', 5, currNode);
					break;
				case '{':
					lastStat = lex分割符;
					currNode = C_Symbol_new(lastStat, '{', 5, currNode);
					break;
				case '}':
					lastStat = lex分割符;
					currNode = C_Symbol_new(lastStat, '}', 5, currNode);
					break;
				case '[':
					lastStat = lex分割符;
					currNode = C_Symbol_new(lastStat, '[', 5, currNode);
					break;
				case ']':
					lastStat = lex分割符;
					currNode = C_Symbol_new(lastStat, ']', 5, currNode);
					break;
				case '=':
					lastStat = lex分割符;
					currNode = C_Symbol_new(lastStat, '=', 5, currNode);
					break;
				case ':':
					lastStat = lex分割符;
					currNode = C_Symbol_new(lastStat, ':', 5, currNode);
					break;
				case ';':
					lastStat = lex分割符;
					currNode = C_Symbol_new(lastStat, ';', 5, currNode);
					break;
				case '+':
					lastStat = lex分割符;
					currNode = C_Symbol_new(lastStat, '+', 5, currNode);
					break;
				case '-':
					lastStat = lex分割符;
					currNode = C_Symbol_new(lastStat, '-', 5, currNode);
					break;
				case '*':
					if (script[i - 1] == '/'){
						currNode->o_type = lex多行注释;
						startPosi = i;
						int offect = i + 1; 
						if (len <= offect){ return rootNode; }
						while (script[offect] == '/' && script[offect-1] == '*'){
							offect++; 
							if (offect >= len){
								printf("游戏结束....\n");
								return rootNode;
							}
						} 
						currLen = offect - startPosi;
						currNode = C_Word_new(lastStat, script, startPosi, currLen, currNode);
						i = offect;
					} else{
						lastStat = lex分割符;
						currNode = C_Symbol_new(lastStat, '*', 5, currNode);
					}
					break;
				case '/'://除法,注释符
					lastStat = lex分割符;
					if (lineIndex <= 0){
						lastStat = lex单行注释;
					} else{
						if (script[i - 1] == '/'){
							currNode->o_type = lex单行注释;
							currNode = C_Symbol_new(lastStat, '/', 5, currNode);
							int offect = i + 1;
							if (len <= offect){ return rootNode; }
							while(script[offect] == '\n') {
								offect++;
								if (len <= offect){ return rootNode; }
							}
							i = offect;
						} else{
							lastStat = lex运算符;
							currNode = C_Symbol_new(lastStat, '/', 5, currNode);
						}
					} 
					break;
				default:
					lastStat = lex分割符;
					printf("打印.未知......%d.......%d.......%c\n", i, cc, cc);
					break;
			}
		}
	}

	return rootNode;
}
//lex单词 = 1, lex数字, lex分割符, lex运算符, lex注释, lex字符串, lex单词链接点, lexNULL,
/// <summary>
/// 符号的创建
/// </summary> 
C_Symbol* C_Symbol_new(csbyte type, char o_data, cstype priority, C_Symbol* currNode){
	size_t size = sizeof(C_Symbol);
	void* p0 = cs_malloc(size);
	C_Symbol* nn = (C_Symbol*)p0;
	nn->o_type = type;
	nn->o_data = o_data;
	nn->priority = priority;
	if (currNode != NULL){
		currNode->o_next = nn;
	}
	printf("创建符号...................................%c\n", o_data);
	return nn;
}
//C_Word* C_Word_new(csbyte type, char* o_data, size_t startPosi, rsize_t o_len, C_Symbol* currNode);
/// <summary>
/// 单词的创建
/// </summary> 
C_Word* C_Word_new(csbyte type, char* currWord, size_t startPosi, size_t o_len, C_Symbol* currNode){
	//printf("创建单词...........%s\n", currWord);
	C_Word* nn = (C_Word*)cs_malloc(sizeof(C_Word));
	nn->o_type = type;
	char* data = (char*)cs_malloc(o_len + 1);
	cs_memcpy(data, currWord, o_len + 1);
	data[o_len] = 0;
	nn->o_data = data;
	nn->o_len = o_len + 1;

	currNode->o_next = nn;
	printf("创建单词....................................%s\n", data);
	return nn;
}